package net.wangds.utils;

import net.wangds.log.helper.LogHelper;

import java.nio.ByteBuffer;

/**
 * 8421格式BCD编码工具.
 * <p></p>
 *
 * @author 王东石 2020/9/21 13:50.
 */
public class Bcd8421Utils extends AbstractBcdUtils {


    /**
     * 数值转为BCD码数据.
     * @param val 编码前数据.
     * @param length 数据长度.
     * @return 编码后的数据.
     */
    public static ByteBuffer toBcdReadModeInit(long val, int length){

        if(val==0){
            if(length>=0){
                return ByteBuffer.wrap(new byte[length]);
            }else{
                return ByteBuffer.wrap(new byte[0]);
            }
        }

        long av = Math.abs(val);

        double log = Math.log10(av);
        double ceil = Math.ceil(log);
        int cnt = (int)(log==ceil?(log+1):ceil);

        ByteBuffer buf = ByteBuffer.allocate(cnt);
        //buf.order(ByteOrder.BIG_ENDIAN);

        //LogHelper.dev("位数:"+length+",cnt:"+cnt);
        int pos = 0;
        for(long v=av;v>0;v=v/10){
            long data = v%10;
            //LogHelper.dev("buf cap:"+buf.capacity()+";pos:"+pos+",data:"+data);
            buf.put(cnt-pos-1, (byte)data);
            pos++;
        }
        buf.position(pos);

        buf.flip();

        if(length>buf.remaining()){
            ByteBuffer temp = ByteBuffer.allocate(length);
            temp.position(length-buf.remaining());
            temp.put(buf);
            buf=temp;
        }

        //buf.flip();
        buf.position(0).limit(buf.capacity());

        return buf;
    }

    /**
     * 数值转为BCD码数据.
     * @param val 编码前数据.
     * @param length 数据长度.
     * @return 编码后的数据.
     */
    public static ByteBuffer toCompactBcdReadModeInit(long val, int length){
        return compact2ReadModInit(toBcdReadModeInit(val, length>0?length*2:-1));
    }

    /**
     * BCD数据转换为数值.
     * @param buf BCD数据.
     * @return 数值.
     */
    public static long toNumber(ByteBuffer buf){
        long res = 0;
        int size = buf.limit();
        for(int i=0;i<buf.limit();i++){
            int v = buf.get(i);
            //LogHelper.dev("取值:"+HexUtils.bytes2HexString(new byte[]{(byte)v}));
            //LogHelper.dev("新值："+Math.pow(10,size-i-1)*v);
            res+=Math.pow(10,size-i-1)*v;
        }
        return res;
    }

    /**
     * 压缩BCD编码解压为数字.
     * @param buf 压缩BCD数据.
     * @return 数值.
     */
    public static long uncompact2Number(ByteBuffer buf){
        return toNumber(uncompact2ReadModInit(buf));
    }




}
